home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 1999 #1 / Amiga Plus 1999 #1.iso / System-Boost / Sound / tmlg / plugins / source / SampleView.cpp < prev   
Encoding:
C/C++ Source or Header  |  1998-08-10  |  22.2 KB  |  939 lines

  1. #include <pragma/exec_lib.h>
  2. #include <pragma/utility_lib.h>
  3. #include <pragma/intuition_lib.h>
  4. #include <pragma/graphics_lib.h>
  5. #include <pragma/commodities_lib.h>
  6. #include <pragma/gadtools_lib.h>
  7. #include <exec/libraries.h>
  8. #include <clib/alib_protos.h>
  9. #include <ClassLibrary/TimerC.h>
  10. #include <ClassLibrary/SemaphoreC.h>
  11. #include <stdlib.h>
  12. #include <math.h>
  13. //#include <debug.h>
  14.  
  15.  
  16. #include "/AudioPluginStructs.h"
  17.  
  18.  
  19. static char Name[] = "SampleView";
  20. static char CopyRight[] = "©Johnny T Nielsen, draco, 1998";
  21.  
  22.  
  23. struct AudioPluginBase {
  24.     struct Library library;
  25. };
  26. #pragma libbase AudioPluginBase;
  27.  
  28.  
  29. struct SaveData
  30. {
  31.     struct PluginData plugindata;   //MUST be the first
  32.     ULONG updates;
  33.     BYTE  pixeldist;
  34.     BOOL vu;
  35.     BOOL cont;
  36. };
  37.  
  38.  
  39. #define VU_WIDTH 5
  40.  
  41.  
  42. struct Library *IntuitionBase = NULL;
  43. struct Library *UtilityBase = NULL;
  44. struct Library *GfxBase = NULL;
  45. struct Library *GadToolsBase = NULL;
  46.  
  47.  
  48. struct NewMenu testmenu[] =
  49. {
  50.     { NM_TITLE, "SampleView", NULL, 0, 0, 0 },
  51.     { NM_ITEM, "Update", NULL, 0, 0, 0 },
  52.     { NM_SUB, "5/s", "1", 0, 0, 0 },
  53.     { NM_SUB, "10/s", "2", 0, 0, 0 },
  54.     { NM_SUB, "15/s", "3", 0, 0, 0 },
  55.     { NM_SUB, "20/s", "4", 0, 0, 0 },
  56.     { NM_SUB, "25/s", "5", 0, 0, 0 },
  57.     { NM_SUB, "50/s", "6", 0, 0, 0 },
  58.     { NM_ITEM, "PixelDistance", NULL, 0, 0, 0 },
  59.     { NM_SUB, "1", NULL, 0, 0, 0 },
  60.     { NM_SUB, "2", NULL, 0, 0, 0 },
  61.     { NM_SUB, "3", NULL, 0, 0, 0 },
  62.     { NM_SUB, "4", NULL, 0, 0, 0 },
  63.     { NM_SUB, "5", NULL, 0, 0, 0 },
  64.     { NM_ITEM, "VU-meter", "v", 0, 0, 0 },
  65.     { NM_ITEM, "Cont. line", "c", 0, 0, 0 },
  66.     { NM_ITEM, NM_BARLABEL, NULL, 0, 0, 0 },
  67.     { NM_ITEM, "Hide", "h", 0, 0, 0 },
  68.     { NM_END, NULL, NULL, 0, 0, 0 }
  69. };
  70.  
  71.  
  72. /****************************************************************************************/
  73.  
  74.  
  75. //{ "MUSTBEDONE"
  76. class MustBeDone {
  77. public:
  78.     MustBeDone();
  79. };
  80.  
  81. MustBeDone mustbedone;
  82.  
  83. MustBeDone::MustBeDone()
  84. {
  85.     Forbid();
  86.     PluginSemaphore *ps = (PluginSemaphore *)FindSemaphore(PLUGIN_SEM_NAME);
  87.     ObtainSemaphore(&ps->Sem);
  88.     Permit();
  89.     ps->IsPlugin = TRUE;
  90.     ps->PluginVer = 0;
  91.     ps->PluginRev = 75;
  92.     ps->PluginName = Name;
  93.     ps->PluginCopyRight = CopyRight;
  94.     ps->PluginFlags = PLUGIN_HAS_WINDOW;
  95.     ReleaseSemaphore(&ps->Sem);
  96. }
  97. //}
  98.  
  99.  
  100. //{ "TestData class"
  101. class TestData : SignalSemaphore {
  102. public:
  103.     ULONG PluginSignal;
  104.     struct Task *plugintask;
  105.     BOOL quitasync;
  106.     struct Task *asynctask;
  107.  
  108.     SaveData savedata;
  109.     ULONG updates;
  110.     BYTE  pixeldist;
  111.     BOOL vu;
  112.     BOOL cont;
  113.     CxObj    *broker;
  114.  
  115.     Window   *window;       //main window
  116.     RastPort *rp;           //it's rastport
  117.     APTR visualinfo;        //it's visualinfo
  118.     struct Menu *menustrip; //it's menu
  119.  
  120.     ULONG samplefreq;
  121.  
  122.     WORD *left, *right;
  123.     ULONG samples;
  124.     ULONG buftime;
  125.     ULONG opsplitning;
  126.     ULONG bufskip;
  127.     ULONG opdwait;
  128.     ULONG bufreached;
  129.  
  130.     SignalSemaphore sem2;
  131.     WORD *left2, *right2;
  132.     ULONG samples2;
  133.     ULONG buftime2;
  134.     ULONG opsplitning2;
  135.     ULONG bufskip2;
  136.     ULONG opdwait2;
  137.     ULONG bufreached2;
  138.  
  139.     BOOL updated;
  140.  
  141.     LONG  vu_decay;
  142.     LONG  vu_gain;
  143.     LONG  vu_old_left;
  144.     LONG  vu_old_right;
  145.  
  146.     ULONG sig;  //send this signal to asynctask to wake it!
  147.     BOOL show;  //TRUE => sampledisplay running
  148.     BOOL show2;
  149.  
  150.     //window inner dimensions
  151.     LONG width, height;
  152.  
  153.     //constructor / destructor
  154.     TestData(CxObj *cx, PluginData *dt);
  155.     ~TestData();
  156.  
  157.     void ClearWindow(BOOL vuclear=TRUE, int channel=3);
  158. };
  159.  
  160.  
  161. TestData::TestData(CxObj *cx, PluginData *dt)
  162.  : broker(NULL)
  163. {
  164.     broker = cx;
  165.     window = NULL;
  166.     rp = NULL;
  167.     if(dt) savedata = *(SaveData *)dt;
  168.     else
  169.     {
  170.         savedata.plugindata.Size = sizeof(struct SaveData);
  171.         savedata.plugindata.ShowMain = TRUE;
  172.         savedata.plugindata.MainX = 0;
  173.         savedata.plugindata.MainY = 0;
  174.         savedata.plugindata.MainW = 200;
  175.         savedata.plugindata.MainH = 100;
  176.         savedata.updates = 25L;
  177.         savedata.vu = FALSE;
  178.         savedata.cont = TRUE;
  179.         savedata.pixeldist = 2;
  180.     }
  181.  
  182.     quitasync = FALSE;
  183.     samplefreq = 0L;
  184.     left = right = NULL;
  185.     samples = 0L;
  186.     buftime = 0L;
  187.     opsplitning = 0L;
  188.     bufskip = 0L;
  189.     bufreached = 0L;
  190.     opdwait = opdwait2 = 40000L;
  191.     show = show2 = FALSE;
  192.  
  193.     updated = FALSE;
  194.  
  195.     vu_decay = 32768L*1/4;
  196.     vu_gain  = 3*(32768-vu_decay);
  197.     vu_old_left = vu_old_right = 0L;
  198.  
  199.     ss_Link.ln_Pri=0;
  200.     ss_Link.ln_Name=NULL;
  201.     ::InitSemaphore(this);
  202.     ss_Link.ln_Name = "SAMPLEVIEW";
  203.     ::AddSemaphore(this);
  204.  
  205.     sem2.ss_Link.ln_Pri=0;
  206.     sem2.ss_Link.ln_Name=NULL;
  207.     ::InitSemaphore(&sem2);
  208.  
  209.     PluginSemaphore *ps = (PluginSemaphore *)FindSemaphore(PLUGIN_SEM_NAME);
  210.     ObtainSemaphore(&ps->Sem);
  211.     PluginSignal = ps->PluginSignal;
  212.     ReleaseSemaphore(&ps->Sem);
  213.     plugintask = FindTask(NULL);
  214. }
  215.  
  216.  
  217. TestData::~TestData()
  218. {
  219.     Forbid();
  220.     ::RemSemaphore(this);
  221.     ::ObtainSemaphore(this);
  222.     ::ReleaseSemaphore(this);
  223.     ss_Link.ln_Name = NULL;
  224.     Permit();
  225. }
  226.  
  227.  
  228. void TestData::ClearWindow(BOOL vuclear, int channel)
  229. {
  230.     if(rp)
  231.     {
  232.         //update display
  233.         LONG width = savedata.plugindata.MainW;
  234.         LONG height = savedata.plugindata.MainH;
  235.         LONG midx = width/2;
  236.         midx-=1;
  237.         LONG midy = height/2;
  238.         LONG channelwidth=width;
  239.         if(right) channelwidth/=2;
  240.  
  241.         //clear window
  242.         if(savedata.vu)
  243.         {
  244.             channelwidth-=(VU_WIDTH+1);
  245.             if(channel & 1)
  246.             {
  247.                 SetAPen(rp, 0);
  248.                 if(vuclear)
  249.                     RectFill(rp, 1,1, channelwidth+VU_WIDTH, height-2);
  250.                 else
  251.                     RectFill(rp, 1,1, channelwidth-2, height-2);
  252.                 SetAPen(rp, 1); //black
  253.  
  254.                 Move(rp, 1, midy);
  255.                 Draw(rp, channelwidth-1, midy); //horisontal midter linie
  256.  
  257.                 Move(rp, channelwidth-1, 1);
  258.                 Draw(rp, channelwidth-1, height-2); //vu delimiter linie
  259.             }
  260.             if(right && (channel & 2))
  261.             {
  262.                 SetAPen(rp, 0);
  263.                 if(vuclear)
  264.                     RectFill(rp, midx+1,1, width-1, height-2);
  265.                 else
  266.                     RectFill(rp, midx+1,1, width-VU_WIDTH-4, height-2);
  267.  
  268.                 SetAPen(rp, 1); //black
  269.                 Move(rp, width-VU_WIDTH-2, 1);
  270.                 Draw(rp, width-VU_WIDTH-2, height-2); //vu delimiter
  271.  
  272.                 Move(rp, midx, midy);
  273.                 Draw(rp, width-VU_WIDTH-2, midy); //horisontal midter line
  274.  
  275.                 Move(rp, midx, 1);
  276.                 Draw(rp, midx, height-1);   //kanal skille linie
  277.             }
  278.         }
  279.         else
  280.         {
  281.             if(channel & 1)
  282.             {
  283.                 SetAPen(rp, 0);
  284.                 RectFill(rp, 1,1, channelwidth-2, height-2);
  285.  
  286.                 SetAPen(rp, 1); //black
  287.                 Move(rp, 1, midy);
  288.                 Draw(rp, channelwidth-2, midy); //horisontal midter linie
  289.             }
  290.             if(right && (channel & 2))
  291.             {
  292.                 SetAPen(rp, 0);
  293.                 RectFill(rp, midx+1,1, width-1, height-2);
  294.  
  295.                 SetAPen(rp, 1);
  296.                 Move(rp, midx, midy);
  297.                 Draw(rp, width-1, midy); //horisontal midter line
  298.  
  299.                 Move(rp, midx, 1);
  300.                 Draw(rp, midx, height-1);   //kanal skille linie
  301.             }
  302.         }
  303.  
  304.         //draw border
  305.         SetAPen(rp, 1); //black
  306.         Move(rp, width-1, 0);
  307.         Draw(rp, width-1, height-1);
  308.         Draw(rp, 0, height-1);
  309.         SetAPen(rp, 2); //white
  310.         Draw(rp, 0, 0);
  311.         Draw(rp, width-1, 0);
  312.     }
  313. }
  314. //}
  315.  
  316.  
  317. //{ "ASYNCTASK"
  318. extern "C" void AsyncTask(void)
  319. {
  320.     struct SignalSemaphore *sem = FindSemaphore("SAMPLEVIEW");
  321.     TestData *data = (TestData *)sem;
  322.     ObtainSemaphore(sem);
  323.     data->sig = AllocSignal(-1);
  324.     ReleaseSemaphore(sem);
  325.     TimerC *timer = new TimerC;
  326.  
  327.     BOOL q=FALSE;
  328.     do
  329.     {
  330.         Wait(1L<<data->sig);
  331.         if(data->show)
  332.         {
  333.             //display running
  334.             while(data->show && !q)
  335.             {
  336.                 ObtainSemaphore(sem);
  337.                 q = data->quitasync;    //shall I quit?
  338.                 timer->Send(0L, data->opdwait);
  339.                 //timer->Send(0L, 250000L);
  340.                 if(data->rp)
  341.                 {
  342.                     //yes - the window was open
  343.                     data->ClearWindow(FALSE, 1);
  344.  
  345.                     LONG width = data->savedata.plugindata.MainW;
  346.                     LONG height = data->savedata.plugindata.MainH;
  347.                     LONG midx = width/2;
  348.                     LONG midy = height/2;
  349.  
  350.                     //show buffer
  351.                     if(data->left)
  352.                     {
  353.                         if((data->opsplitning > data->bufreached) || (data->opsplitning==0L))
  354.                         {
  355.                             LONG max = width/data->savedata.pixeldist;
  356.                             if(data->right) max /= 2;
  357.  
  358.                             LONG channelwidth = width;
  359.                             if(data->right) channelwidth/=2;
  360.                             if(data->savedata.vu) channelwidth-=(VU_WIDTH+1);
  361.  
  362.                             LONG step;
  363.                             step = channelwidth/max;
  364.  
  365.                             LONG factor = 32768/(height-10);
  366.  
  367.                             LONG x = 1;
  368.                             ULONG vu_left = 0;
  369.                             ULONG vu_right = 0;
  370.                             LONG value;
  371.  
  372.                             LONG skip = 2*data->samplefreq/11025;
  373.                             if(skip < 1) skip=1;
  374.                             if(max*skip > data->bufskip) max=data->bufskip/skip;
  375.  
  376.                             SetAPen(data->rp, 1);
  377.                             for(LONG i=0; i<max; i++)
  378.                             {
  379.                                 value = data->left[data->bufreached*data->bufskip + i*skip];
  380.                                 vu_left+=abs(value);
  381.                                 if(i)
  382.                                 {
  383.                                     if(data->savedata.cont)
  384.                                         Draw(data->rp, x+channelwidth*i/max, midy+value/factor);
  385.                                     else
  386.                                         WritePixel(data->rp, x+channelwidth*i/max, midy+value/factor);
  387.                                 }
  388.                                 else
  389.                                 {
  390.                                     Move(data->rp, x+channelwidth*i/max, midy+value/factor);
  391.                                 }
  392.                             }
  393.                             if(data->savedata.vu)
  394.                             {
  395.                                 //for(; i<(data->bufskip/data->savedata.pixeldist); i++)
  396.                                 //{
  397.                                 //    value = data->left[data->bufreached*data->bufskip + i*skip];
  398.                                 //    vu_left+=abs(value);
  399.                                 //}
  400.                                 //vu_left/=(data->bufskip/data->savedata.pixeldist);
  401.                                 vu_left/=max;
  402.                                 vu_left = vu_left*data->vu_gain/32768L+data->vu_decay*data->vu_old_left/32768L;
  403.                                 data->vu_old_left = vu_left;
  404.                                 vu_left /= factor;
  405.  
  406.                                 SetAPen(data->rp, 0);
  407.                                 RectFill(data->rp, channelwidth, 1, channelwidth+(VU_WIDTH-1), height-vu_left);
  408.                                 SetAPen(data->rp, 3);
  409.                                 RectFill(data->rp, channelwidth, height-vu_left, channelwidth+(VU_WIDTH-1), height-2);
  410.                             }
  411.                             if(data->right)
  412.                             {
  413.                                 data->ClearWindow(FALSE, 2);
  414.                                 x = midx;
  415.                                 SetAPen(data->rp, 1);
  416.                                 for(i=0; i<max; i++)
  417.                                 {
  418.                                     value = data->right[data->bufreached*data->bufskip + i*skip];
  419.                                     vu_right+=abs(value);
  420.                                     if(i)
  421.                                     {
  422.                                         if(data->savedata.cont)
  423.                                             Draw(data->rp, x+channelwidth*i/max, midy+value/factor);
  424.                                         else
  425.                                             WritePixel(data->rp, x+channelwidth*i/max, midy+value/factor);
  426.                                     }
  427.                                     else
  428.                                     {
  429.                                         Move(data->rp, x+channelwidth*i/max, midy+value/factor);
  430.                                     }
  431.                                 }
  432.                                 if(data->savedata.vu)
  433.                                 {
  434.                                     //for(; i<(data->bufskip/data->savedata.pixeldist); i++)
  435.                                     //{
  436.                                     //    value = data->right[data->bufreached*data->bufskip + i*skip];
  437.                                     //    vu_right+=abs(value);
  438.                                     //}
  439.                                     //vu_right/=(data->bufskip/data->savedata.pixeldist);
  440.                                     vu_right/=max;
  441.                                     vu_right = vu_right*data->vu_gain/32768L+data->vu_decay*data->vu_old_right/32768L;
  442.                                     data->vu_old_right = vu_right;
  443.                                     vu_right /= factor;
  444.  
  445.                                     SetAPen(data->rp, 0);
  446.                                     RectFill(data->rp, width-VU_WIDTH-1, 1, width-2, height-vu_right);
  447.                                     SetAPen(data->rp, 3);
  448.                                     RectFill(data->rp, width-VU_WIDTH-1, height-vu_right, width-2, height-2);
  449.                                 }
  450.                             }
  451.                             data->bufreached++;
  452.                         }
  453.                     }
  454.                 }
  455.                 else data->show=FALSE;
  456.                 ReleaseSemaphore(sem);
  457.  
  458.                 //test if new data has arrived!
  459.                 ObtainSemaphore(&data->sem2);
  460.                 if(data->updated)
  461.                 {
  462.                     data->left = data->left2;
  463.                     data->right = data->right2;
  464.                     data->samples = data->samples2;
  465.                     data->buftime = data->buftime2;
  466.                     data->opsplitning = data->opsplitning2;
  467.                     data->bufskip = data->bufskip2;
  468.                     data->opdwait = data->opdwait2;
  469.                     data->bufreached = data->bufreached2;
  470.  
  471.                     data->updated = FALSE;
  472.                 }
  473.                 ReleaseSemaphore(&data->sem2);
  474.  
  475.                 if(!q)
  476.                 {
  477.                     timer->WaitTimer();
  478.                     timer->GetTimerMsg();
  479.                 }
  480.             }
  481.         }
  482.         else
  483.         {
  484.             ObtainSemaphore(sem);
  485.             q = data->quitasync;    //shall I quit?
  486.             ReleaseSemaphore(sem);
  487.         }
  488.     }while(! q);
  489.  
  490.     delete timer;
  491.     ObtainSemaphore(sem);
  492.     FreeSignal(data->sig);
  493.     ULONG sig = data->PluginSignal;
  494.     struct Task *task = data->plugintask;
  495.     ReleaseSemaphore(sem);
  496.  
  497.     //tell main that I've heard the request!
  498.     Signal(task, 1L<<sig);
  499.     Wait(0L);
  500. }
  501. //}
  502.  
  503.  
  504. //{ "Quit"
  505. extern "C" void QuitPlugin(register __a0 APTR _data, register __a6 struct Library *base)
  506. {
  507.     TestData *data = (TestData *)_data;
  508.     if(data)
  509.     {
  510.         //get rid of async task
  511.         ObtainSemaphore((SignalSemaphore *)data);
  512.         data->quitasync = TRUE;
  513.         data->show = FALSE;
  514.         Signal(data->asynctask, 1L<<data->sig);
  515.         ReleaseSemaphore((SignalSemaphore *)data);
  516.         Wait(1L<<data->PluginSignal);
  517.  
  518.         DeleteTask(data->asynctask);
  519.  
  520.         //now close window
  521.         if(data->window)
  522.         {
  523.             ClearMenuStrip(data->window);
  524.             FreeMenus(data->menustrip);
  525.             FreeVisualInfo(data->visualinfo);
  526.             Forbid();
  527.             data->window->UserPort = NULL;
  528.             CloseWindow(data->window);
  529.             Permit();
  530.         }
  531.         //and delete the data
  532.         delete data;
  533.     }
  534.     if(GadToolsBase) CloseLibrary(GadToolsBase);
  535.     if(UtilityBase) CloseLibrary(UtilityBase);
  536.     if(IntuitionBase) CloseLibrary(IntuitionBase);
  537.     if(GfxBase) CloseLibrary(GfxBase);
  538. }
  539. //}
  540.  
  541.  
  542. //{ "InitPlugin"
  543. extern "C" APTR InitPlugin(register __a0 PluginData *d, register __a1 struct MsgPort *p, register __a2 CxObj *b,
  544.     register __a6 struct Library *base)
  545. {
  546.     TestData *data = NULL;
  547.     try {
  548.         IntuitionBase = OpenLibrary("intuition.library", 0);
  549.         GfxBase = OpenLibrary("graphics.library", 0);
  550.         UtilityBase = OpenLibrary("utility.library", 0);
  551.         GadToolsBase = OpenLibrary("gadtools.library", 0);
  552.         data = new TestData(b, d);
  553.  
  554.         ObtainSemaphore((SignalSemaphore *)data);
  555.         data->asynctask = CreateTask("SampleView.plugin", 0, AsyncTask, 4096L);
  556.         ReleaseSemaphore((SignalSemaphore *)data);
  557.     }
  558.     catch(...) { };
  559.     return (APTR)data;
  560. }
  561. //}
  562.  
  563.  
  564. //{ "getpluginData"
  565. extern "C" PluginData *GetPluginData(register __a0 APTR _data, register __a6 Library *base)
  566. {
  567.     TestData *data = (TestData *)_data;
  568.     data->savedata.plugindata.ShowMain = (BOOL)data->window;
  569.     if(data->window)
  570.     {
  571.         data->savedata.plugindata.MainX = data->window->LeftEdge;
  572.         data->savedata.plugindata.MainY = data->window->TopEdge;
  573.     }
  574.     data->savedata.plugindata.Size = sizeof(struct SaveData);
  575.     return (PluginData *)&data->savedata;
  576. }
  577. //}
  578.  
  579.  
  580. //{ "InitTransformation"
  581. extern "C" void InitTransformation(register __a0 APTR _data,
  582.     register __a1 char *label,
  583.     register __d0 ULONG duration,
  584.     register __d1 ULONG samplefreq,
  585.     register __d2 ULONG channels,
  586.     register __d3 ULONG bitrate,
  587.     register __d4 ULONG elapsed,
  588.     register __a6 struct Library *base)
  589. {
  590.     TestData *data = (TestData *)_data;
  591.     ObtainSemaphore((SignalSemaphore *)data);
  592.     data->samplefreq = samplefreq;
  593.     data->show = data->show2 = TRUE;
  594.     //dprintf("SAMPLEFREQ: %ld", samplefreq);
  595.     ReleaseSemaphore((SignalSemaphore *)data);
  596.     Signal(data->asynctask, 1L<<data->sig);
  597. }
  598. //}
  599.  
  600.  
  601. //{ "Transform"
  602. extern "C" void Transform(register __a0 APTR _data, register __a1 WORD *left, register __a2 WORD *right, register __d0 ULONG samples,
  603.     register __a6 struct Library *base)
  604. {
  605.     //TestData *data = (TestData *)_data;
  606. }
  607. //}
  608.  
  609.  
  610. //{ "PluginDisplay"
  611. extern "C" void PluginDisplay(register __a0 APTR _data, register __a1 WORD *left, register __a2 WORD *right, register __d0 ULONG samples,
  612.     register __a6 struct Library *base)
  613. {
  614.     TestData *data = (TestData *)_data;
  615.     //dprintf("SAMPLES   : %ld", samples);
  616.     //ObtainSemaphore((SignalSemaphore *)data);
  617.     if(AttemptSemaphore((SignalSemaphore *)data))
  618.     {
  619.         data->left = left;
  620.         data->right = right;
  621.         data->samples = samples;
  622.  
  623.         data->buftime = data->samplefreq/samples; //number of buffers this size a second
  624.         data->opsplitning = data->savedata.updates*samples/data->samplefreq; //split each buffer <opsplitning> times
  625.         if(data->opsplitning)
  626.         {
  627.             data->bufskip = samples/data->opsplitning;
  628.             data->opdwait = 1000000L / 25; //(data->samplefreq * data->opsplitning / samples);
  629.         }
  630.         else
  631.         {
  632.             data->bufskip = samples;
  633.             data->opdwait = 1000000L / data->buftime;
  634.         }
  635.         data->bufreached = 0;
  636.  
  637.         ReleaseSemaphore((SignalSemaphore *)data);
  638.     }
  639.     else
  640.     {
  641.         ObtainSemaphore(&data->sem2);
  642.         data->left2 = left;
  643.         data->right2 = right;
  644.         data->samples2 = samples;
  645.  
  646.         data->buftime2 = data->samplefreq/samples; //number of buffers this size a second
  647.         data->opsplitning2 = data->savedata.updates*samples/data->samplefreq; //split each buffer <opsplitning> times
  648.         if(data->opsplitning2)
  649.         {
  650.             data->bufskip2 = samples/data->opsplitning2;
  651.             data->opdwait2 = 1000000L / 25L //(data->samplefreq * data->opsplitning2 / samples);
  652.         }
  653.         else
  654.         {
  655.             data->bufskip2 = samples;
  656.             data->opdwait2 = 1000000L / data->buftime2;
  657.         }
  658.         data->bufreached2 = 0;
  659.  
  660.         data->updated = TRUE;
  661.  
  662.         ReleaseSemaphore(&data->sem2);
  663.     }
  664. }
  665. //}
  666.  
  667.  
  668. //{ "EndTransformation"
  669. extern "C" void EndTransformation(register __a0 APTR _data, register __a6 struct Library *base)
  670. {
  671.     TestData *data = (TestData *)_data;
  672.     ObtainSemaphore((SignalSemaphore *)data);
  673.     data->samplefreq = 0L;
  674.     data->left = NULL;
  675.     data->show = data->show2 = FALSE;
  676.     Signal(data->asynctask, 1L<<data->sig);
  677.     ReleaseSemaphore((SignalSemaphore *)data);
  678.     data->ClearWindow();
  679. }
  680. //}
  681.  
  682.  
  683. //{ "HiddenPlugin"
  684. extern "C" BOOL HiddenPlugin(register __a0 APTR _data, register __a6 struct Library *base)
  685. {
  686.     TestData *data = (TestData *)_data;
  687.     if(data->window) return FALSE;
  688.     return TRUE;
  689. }
  690. //}
  691.  
  692.  
  693. //{ "ShowPlugin"
  694. extern "C" BOOL ShowPlugin(register __a0 APTR _data, register __a1 MsgPort *port, register __a6 struct Library *base)
  695. {
  696.     TestData *data = (TestData *)_data;
  697.     BOOL res = FALSE;
  698.     ObtainSemaphore((SignalSemaphore *)data);
  699.     if(! data->window)
  700.     {
  701.         data->window = OpenWindowTags(NULL,
  702.             WA_Left, data->savedata.plugindata.MainX,
  703.             WA_Top, data->savedata.plugindata.MainY,
  704.             WA_InnerWidth, data->savedata.plugindata.MainW,
  705.             WA_InnerHeight, data->savedata.plugindata.MainH,
  706.             WA_MinHeight, 25,
  707.             WA_MinWidth, 75,
  708.             WA_MaxHeight, -1,
  709.             WA_MaxWidth, -1,
  710.             WA_Title, "SampleView for TMLG",
  711.             WA_ScreenTitle, "SampleView for TMLG, ©Johnny T Nielsen, 1998",
  712.             WA_SizeGadget, TRUE,
  713.             WA_DragBar, TRUE,
  714.             WA_DepthGadget, TRUE,
  715.             WA_CloseGadget, TRUE,
  716.             WA_SmartRefresh, TRUE,
  717.             WA_GimmeZeroZero, TRUE,
  718.             WA_IDCMP, NULL,
  719.             TAG_DONE);
  720.         if(data->window)
  721.         {
  722.             data->visualinfo = GetVisualInfo(data->window->WScreen, TAG_END);
  723.             data->menustrip = CreateMenus(testmenu, TAG_END);
  724.             LayoutMenus(data->menustrip, data->visualinfo, TAG_END);
  725.             SetMenuStrip(data->window, data->menustrip);
  726.  
  727.             data->rp = data->window->RPort;
  728.             data->window->UserPort = port;
  729.             ModifyIDCMP(data->window, IDCMP_CLOSEWINDOW | IDCMP_MENUPICK | IDCMP_NEWSIZE);
  730.             res = TRUE;
  731.  
  732.             data->ClearWindow();
  733.  
  734.             data->show = data->show2;
  735.             Signal(data->asynctask, 1L<<data->sig);
  736.         }
  737.     }
  738.     ReleaseSemaphore((SignalSemaphore *)data);
  739.     return res;
  740. }
  741. //}
  742.  
  743.  
  744. //{ "hideplugin"
  745. extern "C" void HidePlugin(register __a0 APTR _data, register __a6 struct Library *base)
  746. {
  747.     TestData *data = (TestData *)_data;
  748.     ObtainSemaphore((SignalSemaphore *)data);
  749.     if(data->window)
  750.     {
  751.         //stop display
  752.         data->show2 = data->show;
  753.         data->show = FALSE;
  754.         Signal(data->asynctask, 1L<<data->sig);
  755.         //close window
  756.         ClearMenuStrip(data->window);
  757.         FreeMenus(data->menustrip);
  758.         FreeVisualInfo(data->visualinfo);
  759.         Forbid();
  760.         data->window->UserPort = NULL;
  761.         CloseWindow(data->window);
  762.         Permit();
  763.         data->window = NULL;
  764.         data->rp = NULL;
  765.     }
  766.     ReleaseSemaphore((SignalSemaphore *)data);
  767. }
  768. //}
  769.  
  770.  
  771. //{ "AboutPlugin"
  772. extern "C" BOOL AboutPlugin(register __a0 APTR _data, register __a1 MsgPort *port, register __a6 struct Library *base)
  773. {
  774.     TestData *data = (TestData *)_data;
  775.     return FALSE;
  776. }
  777. //}
  778.  
  779.  
  780. //{ "PluginPrefs"
  781. extern "C" BOOL PluginPrefs(register __a0 APTR _data, register __a1 MsgPort *port, register __a6 struct Library *base)
  782. {
  783.     TestData *data = (TestData *)_data;
  784.     return FALSE;
  785. }
  786. //}
  787.  
  788.  
  789. //{ "PluginHandleKey"
  790. extern "C" BOOL PluginHandleKey(register __a0 APTR _data, register __d0 ULONG key, register __a6 struct Library *base)
  791. {
  792.     TestData *data = (TestData *)_data;
  793.     return FALSE;
  794. }
  795. //}
  796.  
  797.  
  798. //{ "HandleWindowMsg"
  799. extern "C" BOOL HandleWindowMsg(register __a0 APTR _data, register __a1 IntuiMessage **msg, register __a6 struct Library *base)
  800. {
  801.     TestData *data = (TestData *)_data;
  802.     if((*msg)->IDCMPWindow == data->window)
  803.     {
  804.         switch((*msg)->Class)
  805.         {
  806.             case IDCMP_NEWSIZE:
  807.                 data->savedata.plugindata.MainX = data->window->LeftEdge;
  808.                 data->savedata.plugindata.MainY = data->window->TopEdge;
  809.                 data->savedata.plugindata.MainW = data->window->Width - data->window->BorderLeft - data->window->BorderRight;
  810.                 data->savedata.plugindata.MainH = data->window->Height - data->window->BorderTop - data->window->BorderBottom;
  811.                 data->ClearWindow();
  812.                 break;
  813.             case IDCMP_CLOSEWINDOW:
  814.                 ReplyMsg((Message *)(*msg));
  815.                 (*msg) = NULL;
  816.                 //close window
  817.                 if(data->window)
  818.                 {
  819.                     data->show2 = data->show;
  820.                     data->show = FALSE;
  821.                     Signal(data->asynctask, 1L<<data->sig);
  822.  
  823.                     ObtainSemaphore((SignalSemaphore *)data);
  824.                     ClearMenuStrip(data->window);
  825.                     FreeMenus(data->menustrip);
  826.                     FreeVisualInfo(data->visualinfo);
  827.                     Forbid();
  828.                     data->window->UserPort = NULL;
  829.                     CloseWindow(data->window);
  830.                     Permit();
  831.                     data->window = NULL;
  832.                     data->rp = NULL;
  833.                     ReleaseSemaphore((SignalSemaphore *)data);
  834.                 }
  835.                 break;
  836.             case IDCMP_MENUPICK:
  837.                 switch((*msg)->Code)
  838.                 {
  839.                     // updates
  840.                     case 0x0000:    // 5/s
  841.                         data->savedata.updates = 5;
  842.                         break;
  843.                     case 0x0800:    // 10/s
  844.                         data->savedata.updates = 10;
  845.                         break;
  846.                     case 0x1000:    // 15/s
  847.                         data->savedata.updates = 15;
  848.                         break;
  849.                     case 0x1800:    // 20/s
  850.                         data->savedata.updates = 20;
  851.                         break;
  852.                     case 0x2000:    // 25/s
  853.                         data->savedata.updates = 25;
  854.                         break;
  855.                     case 0x2800:    // 50/s
  856.                         data->savedata.updates = 50;
  857.                         break;
  858.                     // pixel distance
  859.                     case 0x0020:    // 1
  860.                         data->savedata.pixeldist = 1;
  861.                         break;
  862.                     case 0x0820:    // 2
  863.                         data->savedata.pixeldist = 2;
  864.                         break;
  865.                     case 0x1020:    // 3
  866.                         data->savedata.pixeldist = 3;
  867.                         break;
  868.                     case 0x1820:    // 4
  869.                         data->savedata.pixeldist = 4;
  870.                         break;
  871.                     case 0x2020:    // 5
  872.                         data->savedata.pixeldist = 5;
  873.                         break;
  874.                     // VU meter
  875.                     case 0xF840:
  876.                         if(data->savedata.vu) data->savedata.vu = FALSE;
  877.                         else data->savedata.vu = TRUE;
  878.                         break;
  879.                     // cont line
  880.                     case 0xF860:
  881.                         if(data->savedata.cont) data->savedata.cont = FALSE;
  882.                         else data->savedata.cont = TRUE;
  883.                         break;
  884.                     // hide
  885.                     case 0xF8A0:
  886.                         HidePlugin(data, base);
  887.                         break;
  888.                 }
  889.                 break;
  890.         }
  891.         //if(*msg)
  892.         //{
  893.         //    ReplyMsg((Message *)(*msg));
  894.         //    (*msg) = NULL;
  895.         //}
  896.         return TRUE;
  897.     }
  898.     return FALSE;
  899. }
  900. //}
  901.  
  902.  
  903. //{ "LockPluginGUI"
  904. extern "C" void LockPluginGUI(register __a0 APTR _data, register __a6 struct Library *base)
  905. {
  906.     TestData *data = (TestData *)_data;
  907.     if(data->window)
  908.     {
  909.         SetWindowPointer(data->window,
  910.             WA_BusyPointer, TRUE,
  911.             WA_PointerDelay, TRUE,
  912.             TAG_DONE);
  913.     }
  914. }
  915. //}
  916.  
  917.  
  918. //{ "UnLockPluginGUI"
  919. extern "C" void UnLockPluginGUI(register __a0 APTR _data, register __a6 struct Library *base)
  920. {
  921.     TestData *data = (TestData *)_data;
  922.     if(data->window)
  923.     {
  924.         SetWindowPointer(data->window,
  925.             TAG_DONE);
  926.     }
  927. }
  928. //}
  929.  
  930.  
  931. //{ "PluginPriority"
  932. extern "C" void PluginPriority(register __a0 APTR _data, register __d0 LONG pri, register __a6 struct Library *base)
  933. {
  934.     TestData *data = (TestData *)_data;
  935.     SetTaskPri(data->asynctask, pri);
  936. }
  937. //}
  938.  
  939.